﻿<style>
.custom-upload-dragger .el-upload-dragger-custombody .el-upload-list__item-name {
  padding-left: 10px;
}

.el-upload-dragger-custombody {
  overflow-y: auto;
}

.el-upload-dragger-custombody .el-upload--picture-card {
  display: none;
}

.custom-upload-dragger .el-upload-list__item-name {
  color: #606266;
  display: block;
  margin-right: 10px;
  overflow: hidden;
  padding-left: 4px;
  text-overflow: ellipsis;
  -webkit-transition: color .3s;
  transition: color .3s;
  white-space: nowrap;
}

.custom-upload-dragger .el-upload-dragger-custombody .el-upload-list__item-status-label, .el-upload-dragger-custombody .el-upload-list__item .el-icon-close {
  right: 10px;
}

.readonly .el-upload-list__item-status-label, .readonly .el-icon-close, .readonly .el-icon-close-tip {
  display: none !important;
}
</style>
<template>
  <div :class="disabled?'custom-upload-dragger readonly':'custom-upload-dragger'">
    <div class="el-upload-dragger-customheader">{{ title }}</div>
    <el-upload v-if="showFileList==false"
               class="el-upload-dragger-custombody"
               drag
               :action="action"
               :headers="headers"
               :data="data"
               :name="name"
               :show-file-list="false"
               :file-list="fileList"
               :limit="limit"
               :accept="accept"
               :on-preview="onPreview"
               :on-remove="onRemove"
               :before-upload="beforeUpload"
               :on-success="handleSuccess"
               :on-error="onError"
               :on-change="handleChange"
               :on-progress="$loading"
               multiple>
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
    </el-upload>
    <el-upload v-else
               class="el-upload-dragger-custombody"
               :action="action"
               :headers="headers"
               :data="data"
               :drag="drag"
               :name="name"
               :show-file-list="showFileList"
               :accept="accept"
               :on-preview="onPreview"
               :on-remove="handleRemove"
               :before-remove="handleBeforeRemove"
               :before-upload="beforeUpload"
               :on-success="onSuccess"
               :on-error="onError"
               :file-list="fileList"
               :list-type="listType"
               :on-change="handleChange"
               multiple>
      <div v-if="listType=='picture-card'" slot="file" slot-scope="{file}">
        <img
            class="el-upload-list__item-thumbnail"
            :src="file.url" alt=""
        >
        <span class="el-upload-list__item-actions">
        <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
        >
          <i class="el-icon-zoom-in"></i>
        </span>
        <span
            class="el-upload-list__item-delete"
            @click="downloadFile(file)"
        >
          <i class="el-icon-download"></i>
        </span>
        <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file,fileList)"
        >
          <i class="el-icon-delete"></i>
        </span>
      </span>
      </div>
    </el-upload>
    <el-dialog :title="dialogTitle" v-if="listType=='picture-card'" :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
    <el-dialog v-else title="操作确认" width="30%" :visible.sync="previewConfirmVisible" append-to-body>
      <span>请选择需要的操作</span>
      <span slot="footer" class="dialog-footer">
      <el-button @click="previewFile(currentFile)">预览</el-button>
      <el-button type="primary" @click="downloadFile(currentFile)">下载</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
function noop() {
}

export default {
  name: "UploadDragger",
  // props:{
  //   title: {},action:{},headers:{},data:{},name:{},showFileList:{type:Array,default:false}
  //   ,accept:{},'on-preview':{},'on-remove':{},fileList:{type:Array,default:()=>{return []}}
  // },
  props: {
    title: {},
    action: {
      type: String,
      default() {
        return Vue.prototype.$ctx + '/file/upload';
      }
    },
    headers: {
      type: Object,
      default() {
        return {};
      }
    },
    data: Object,
    multiple: Boolean,
    name: {
      type: String,
      default: 'file'
    },
    drag: Boolean,
    withCredentials: Boolean,
    showFileList: {
      type: Boolean,
      default: true
    },
    accept: String,
    type: {
      type: String,
      default: 'select'
    },
    beforeUpload: Function,
    beforeRemove: {
      type: Function, default: noop
    },
    onRemove: {
      type: Function,
      default: (file, fileList) => {},
    },
    onChange: {
      type: Function,
      default: noop
    },
    // onPreview: {
    //     type: Function,
    // default:(file) => {
    //     this.previewConfirmVisible = true;
    //     this.currentFile = file;
    // window.open(Vue.prototype.$ctx+'/file/download/'+file.id);
    // }
    // },
    onSuccess: {
      type: Function,
      default: noop
    },
    onProgress: {
      type: Function,
      default: noop
    },
    onError: {
      type: Function,
      default: noop
    },
    fileList: {
      type: Array,
      default() {
        return [];
      }
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    listType: {
      type: String,
      default: 'text' // text,picture,picture-card
    },
    httpRequest: Function,
    disabled: Boolean,
    limit: Number,
    onExceed: {
      type: Function,
      default: noop
    }
  },
  data() {
    return {
      previewConfirmVisible: false,
      currentFile: {},
      dialogImageUrl: '',
      dialogVisible: false,
      dialogTitle: '',
    }
  },
  watch: {
    fileList() {
      if (this.fileList && this.fileList.length > 0) {
        for (var item of this.fileList) {
          if (!item.url) {
            item.url = this.$ctx + '/file/download/' + item.id;
          }
        }
      }
    }
  },
  methods: {
    onPreview(file) {
      if (window.filePreviewSupports && file.name && file.name.lastIndexOf('.') >= 0) {
        var fileType = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length);
        var support = false;
        for (var item of window.filePreviewSupports) {
          if (fileType == item) {
            support = true;
            break;
          }
        }
        if (!support) {
          return this.downloadFile(file);
        }
      }
      this.previewConfirmVisible = true;
      this.currentFile = file;
    },
    downloadFile(file) {
      this.previewConfirmVisible = false;
      window.open(Vue.prototype.$ctx + '/file/download/' + file.id);
    },
    previewFile(file) {
      this.previewConfirmVisible = false;
      window.open(Vue.prototype.$ctx + '/file/preview/' + file.id);
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
      this.dialogTitle = file.name;
    },
    handleChange(file, fileList) {
      this.fileList.splice(0, this.fileList.length);
      for (var item of fileList) {
        this.fileList.push(item);
      }
      this.onChange(file, fileList);
    },
    handleSuccess(response, file, fileList) {
      if (response.code != 0) {
        for (var i = 0; i < fileList.length; i++) {
          var item = fileList[i];
          if (item === file) {
            fileList.splice(i, 1);
          }
        }
        this.$message.error(response.msg);
        return;
      }
      if (response.data) {
        file.id = response.data;
        file.url = this.$ctx + '/file/download/' + file.id;
      }
      setTimeout(() => {
        this.$loading().close();
      }, 1000);
      this.onSuccess(response, file, fileList);
    },
    handleRemove(file, fileList) {
      this.$loading();
      this.$post("/file/delete/" + file.id, {}, (data) => {
        if (this.fileList === fileList) {
          for (var i = 0; i < fileList.length; i++) {
            var item = fileList[i];
            if (item.id == file.id) {
              this.fileList.splice(i, 1);
              break;
            }
          }
          return;
        }
        this.fileList.splice(0, this.fileList.length);
        for (var item of fileList) {
          if (item.id == file.id) {
            continue;
          }
          this.fileList.push(item);
        }
      }, data => {
        setTimeout(() => {
          this.$loading().close();
        }, 1000);
        if (data.code != 0) {
          fileList.push(file);
          return;
        }
      });
      this.onRemove(file, fileList);
    },
    handleBeforeRemove(file, fileList) {
      if (this.beforeRemove == noop) {
        return this.$confirm(`确定移除 ${file.name}？`);
      }
      return this.beforeRemove(file, fileList);
    },
  }
}
</script>
